package com.junwei.smsdemo.service.impl;

import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.junwei.smsdemo.constant.Constants;
import com.junwei.smsdemo.dto.SendSmsDto;
import com.junwei.smsdemo.dto.VerifyCodeDto;
import com.junwei.smsdemo.exception.SmsException;
import com.junwei.smsdemo.service.SmsService;
import com.junwei.smsdemo.util.AssertUtil;
import com.junwei.smsdemo.util.RedisUtil;
import com.junwei.smsdemo.util.SmsUtil;
import com.junwei.smsdemo.vo.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

/**
 * @description: 短信服务->腾讯云
 * @author: gsy
 * @create: 2020-09-26 13:24
 */
@Service
@Slf4j
public class SmsServiceImpl implements SmsService {

    @Autowired
    private SmsSingleSender smsSingleSender;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 短信模板ID
     **/
    @Value("${smsconfig.templateid}")
    private int TEMPLATE_ID;
    /**
     * 短信签名内容
     */
    @Value("${smsconfig.smsSign}")
    private String SMS_SIGN;

    //验证码失效时间
    @Value("${smsconfig.invalidtime}")
    private String INVALID_TIME;

    @Value("${smsconfig.phone-prefix}")
    private String PHONE_PREFIX;

    @Override
    public void sendSmsCode(SendSmsDto sendSmsDto) {
        // 可以在发送验证码之前对当前手机号做一些验证，如该手机号是否注册过
        // 为了防止短信轰炸可以根据业务需求在此做一些限制
        String code = SmsUtil.getCode();
        try {
            ArrayList<String> params = new ArrayList<>();
            params.add(code);
            params.add(INVALID_TIME);
            SmsSingleSenderResult senderResult = smsSingleSender
                    .sendWithParam("86", sendSmsDto.getMobile(),
                            TEMPLATE_ID, params, SMS_SIGN, "", "");
            int statusCode = senderResult.result;
            String statusMsg = senderResult.errMsg;
            log.info("发送短信，腾讯云返回状态码：" + statusCode);
            log.info("发送短信，腾讯云返回信息：" + statusMsg);
            // 过于频繁
            if (Constants.SEND_SMS_CODE_FREQUENT == statusCode) {
                throw new SmsException(R.USER_LOGIN_ERROR3, "");
            }
            // 达到上限
            if (Constants.SEND_SMS_CODE_UPPER == statusCode) {
                throw new SmsException(R.USER_CODE_TOOMANY, "");
            }
            if (Constants.SEND_SMS_CODE_SUCCESS != statusCode) {
                throw new SmsException(R.sms_send_error, "");
            }
            //存入redis 五分钟:60*5
            if (!redisUtil.setCacheObject(SmsUtil.map.get(sendSmsDto.getType()) + sendSmsDto.getMobile(),
                    code, 60 * Integer.parseInt(INVALID_TIME))) {
                throw new SmsException(R.sms_send_error, "");
            }
        } catch (Exception e) {
            throw new SmsException(R.sms_send_error, "");
        }
    }

    @Override
    public void verifyCode(VerifyCodeDto verifyCodeDto) {
        String redisCode = (String) redisUtil.getCacheObject(SmsUtil.map
                .get(verifyCodeDto.getType()) + verifyCodeDto.getMobile());
        AssertUtil.isNull(redisCode, R.USER_LOGIN_ERROR4);
        if (redisCode.equals(verifyCodeDto.getCode())) {
            redisUtil.delete(SmsUtil.map.get(verifyCodeDto.getType()) + verifyCodeDto.getMobile());
        } else {
            throw new SmsException(R.USER_CODE_ERROR, "");
        }
    }
}
